package com.code.test.second.hash;

import java.util.ArrayList;
import java.util.List;

/**
 * 1002. 查找常用字符
 * 力扣题目链接
 * <p>
 * 给你一个字符串数组 words ，请你找出所有在 words 的每个字符串中都出现的共用字符（ 包括重复字符），并以数组形式返回。你可以按 任意顺序 返回答案。
 * <p>
 * 示例 1：
 * <p>
 * 输入：words = ["bella","label","roller"] 输出：["e","l","l"]
 * <p>
 * 示例 2：
 * <p>
 * 输入：words = ["cool","lock","cook"] 输出：["c","o"]
 * <p>
 * 提示：
 * <p>
 * 1 <= words.length <= 100 1 <= words[i].length <= 100 words[i] 由小写英文字母组成
 */
public class SCode1002 {
    public static void main(String[] args) {
        String[] input = {"bella", "label", "roller"};
        System.out.println(commonCharsB(input));

    }

    /**
     * 找出每个字符串共同的子集
     * 其实就是26个小写字符中在所有串都出现
     */
    public static List<String> commonChars(String[] s) {
        int[] hash = new int[26];
        String first = s[0];
        int len = first.length();
        //算出第一个字符串每个字符出现的数量
        for (int i = 0; i < len; i++) {
            char c = first.charAt(i);
            hash[c - 'a']++;
        }

        //算出数组剩下字符中有相同数量的字符

        for (int i = 1; i < s.length; i++) {
            int[] anotherHash = new int[26];
            String curStr = s[i];
            int curLen = curStr.length();
            //然后统计出这个字符串每个字符的数量
            for (int j = 0; j < curLen; j++) {
                char c = curStr.charAt(j);
                anotherHash[c - 'a']++;
            }

            //然后是拿anotherHash区跟第一个的hash对比，把交集留下来
            for (int k = 0; k < 26; k++) {
                //保证第一个hash里面统计的26个字符在所有字符串里出现的最小次数
                //如果第二个字符中某个字符出现的个数小于第一个字符串，那么每个字符最大公共个数就应该是最小的那个
                //因为要取的是公共的，所以只能取最小的公共字符
                /**
                 * 比如 第一个串 bella  : b 1 e 1 ll 2 a 1
                 *     第二个串 label  : ll 2 a 1 e 1
                 */
                hash[k] = Math.min(hash[k], anotherHash[k]);
            }

        }

        List<String> result = new ArrayList<>();
        for (int i = 0; i < 26; i++) {
            //这里是while，因为同一个字符可能出现多次
            /**
             * 先判断hash[i]是否有该字符，再判断有没有多个，把多个连起来放到结果集
             */
            while (hash[i] != 0) {
                char c = (char) (i + 'a');
                result.add(String.valueOf(c));
                hash[i]--;
            }
        }

        return result;
    }


    public static List<String> commonCharsB(String[] s) {

        /**
         * 先取第一个字符串，算出每个字符的数量
         * 再取剩下的字符串，也算出每个字符的数量，然后计算相同字符的最小数量
         */

        String first = s[0];
        int firstLen = first.length();
        int[] hash = new int[26];
        for (int i = 0; i < firstLen; i++) {
            char c = first.charAt(i);
            hash[c - 'a']++;
        }

        for (int i = 1; i < s.length; i++) {
            int[] otherHash = new int[26];
            String curStr = s[i];
            int curLen = curStr.length();

            for (int j = 0; j < curLen; j++) {
                char c = curStr.charAt(j);
                otherHash[c - 'a']++;
            }

            for (int k = 0; k < 26; k++) {
                hash[k] = Math.min(hash[k], otherHash[k]);
            }
        }


        List<String> result = new ArrayList<>();

        for (int i = 0; i < 26; i++) {
            while (hash[i] != 0) {
                char c = (char) (i + 'a');
                result.add(String.valueOf(c));
                hash[i]--;
            }
        }
        return result;
    }
}
